package ${package};

import ${packageBase}.core.builder.Page;
import ${packageBase}.core.builder.WhereCondition;
import ${packageBase}.core.exception.ImsException;
import ${packageBase}.core.jooq.tables.pojos.${className};
import ${packageBase}.core.jooq.tables.records.${className}Record;
import ${packageBase}.core.model.PageInfo;
import ${packageBase}.core.utils.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.jooq.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;

import static ${packageBase}.core.jooq.tables.${className}.${tableName?upper_case};

/**
 * ${tableComment} 数据库数据操作层
 *
 * @author motorfu
 * @email ffu@maxleap.com
 * @since ${date}
 */
@Slf4j
@Component
public class ${className}Dao implements BaseDao<${className}, ${className}Record> {

  private final DSLContext dsl;

  @Autowired
  public ${className}Dao(DSLContext dsl) {
    this.dsl = dsl;
  }

  @Override
  public DSLContext dsl() {
    return this.dsl;
  }

  /**
   * select 合成方法， 包含是否删除条件
   *
   * @return
   */
  @Override
  public SelectConditionStep<${className}Record> select() {
    SelectConditionStep<${className}Record> selectConditionStep = this.dsl.selectFrom(${tableName?upper_case})
        .where(${tableName?upper_case}.IS_DELETED.eq(false));
    return selectConditionStep;
  }

  /**
   * 查询返回指定字段
   *
   * @param selectFields
   * @return
   */
  public SelectConditionStep<?> select(SelectField... selectFields) {
    SelectConditionStep<?> selectConditionStep = this.dsl.select(selectFields).from(${tableName?upper_case})
        .where(${tableName?upper_case}.IS_DELETED.eq(false));
    return selectConditionStep;
  }

  /**
   * 根据查询条件
   * 查询返回指定字段
   *
   * @param condition
   * @param selectFields
   * @return
   */
  public SelectConditionStep<?> select(Condition condition, SelectField... selectFields) {
    if (condition == null) {
      throw new ImsException("查询条件不能为空");
    }
    SelectConditionStep<?> selectConditionStep = this.dsl.select(selectFields).from(${tableName?upper_case})
        .where(${tableName?upper_case}.IS_DELETED.eq(false)).and(condition);
      return selectConditionStep;
  }

  /**
   * 返回自定义模型 当条数据
   *
   * @param condition
   * @param targetClass
   * @param selectFields
   * @return
   */
  @Override
  public <E> E find(Condition condition, Class<E> targetClass, SelectField... selectFields) {
    Record record = select(condition, selectFields).limit(1).fetchOne();
    if (record != null) {
      return record.into(targetClass);
    }
    return null;
  }

  /**
   * 获取当条数据
   *
   * @param condition
   * @param selectFields
   * @return
   */
  @Override
  public ${className} find(Condition condition, SelectField... selectFields) {
    Record record = select(condition, selectFields).limit(1).fetchOne();
    if (record != null) {
      return record.into(${className}.class);
    }
    return null;
  }

  /**
   * update 合成方法， 包含是否删除条件
   *
   * @param entity
   * @return
   */
  @Override
  public UpdateConditionStep<${className}Record> update(${className} entity) {
    ${className}Record record = dsl().newRecord(${tableName?upper_case}, entity);
    record.setLastModified(System.currentTimeMillis());
    record.setLastModifiedBy(getPrincipal());
    UpdateConditionStep<${className}Record> selectConditionStep = this.dsl.update(${tableName?upper_case})
      .set(record).where(${tableName?upper_case}.IS_DELETED.eq(false).and(${tableName?upper_case}.ID.eq(entity.getId())));
    return selectConditionStep;
  }

  @Override
  public ${className} create(${className} entity) {
    ${className}Record record = dsl().newRecord(${tableName?upper_case}, entity);
    record.setCreated(System.currentTimeMillis());
    record.setCreatedBy(getPrincipal());
    return dsl().insertInto(${tableName?upper_case}).set(record).returning().fetchOne().into(${className}.class);
  }

  /**
   * 查询一条记录
   *
   * @param id
   * @return
   */
  @Override
  public ${className} find(Long id) {
    ${className}Record record = select().and(${tableName?upper_case}.ID.eq(id)).fetchOne();
    if (record == null) return null;
    return record.into(${className}.class);
  }

  /**
   * 按照条件查询
   *
   * @param whereCondition
   * @return
   */
  @Override
  public List<${className}> findList(WhereCondition whereCondition) {
    if (whereCondition == null) {
      throw new ImsException("查询条件不能为空");
    }
    return findList(whereCondition.getCondition());
  }

  /**
   * 按照条件查询
   *
   * @param condition
   * @return
   */
  @Override
  public List<${className}> findList(Condition condition) {
    if (condition == null) {
      throw new ImsException("查询条件不能为空");
    }
    return select().and(condition).fetchInto(${className}.class);
  }

  /**
   * 查询数据
   *
   * @param limit
   * @return
   */
  @Override
  public List<${className}> findList(int limit) {
    return select().limit(limit).fetchInto(${className}.class);
  }

  /**
   * 按照条件查询
   * @param condition
   * @param limit
   * @return
   */
  @Override
  public List<${className}> findList(Condition condition, int limit) {
    if (condition == null) {
      throw new ImsException("查询条件不能为空");
    }
    return select().and(condition).limit(limit).fetchInto(${className}.class);
  }

  /**
   * 删除数据 可恢复
   *
   * @param id
   * @return
   */
  @Override
  public int remove(Long id) {
    return removes(id);
  }

  /**
  * 批量删除数据
  *
  * @param ids
  * @return
  */
  @Override
  public int removes(List<Long> ids) {
    if (ids == null || ids.size() <= 0) {
      return 0;
    }
    return removes(ids.toArray(new Long[ids.size()]));
  }

  /**
  * 批量删除数据
  *
  * @param ids
  * @return
  */
  @Override
  public int removes(Long... ids) {
    if (ids == null || ids.length <= 0) {
      return 0;
    }
    int result = this.dsl.update(${tableName?upper_case})
        .set(${tableName?upper_case}.IS_DELETED, true)
        .set(${tableName?upper_case}.LAST_MODIFIED, System.currentTimeMillis())
        .set(${tableName?upper_case}.LAST_MODIFIED_BY, getPrincipal())
        .where(${tableName?upper_case}.IS_DELETED.eq(false)
        .and(${tableName?upper_case}.ID.in(ids)))
        .execute();
    return result;
  }

  /**
   * 删除数据，无法恢复
   *
   * @param id
   * @return
   */
  @Override
  public int delete(Long id) {
    return dsl().deleteFrom(${tableName?upper_case}).where(${tableName?upper_case}.ID.eq(id)).execute();
  }

  /**
   * 更新数据
   *
   * @param entity
   * @return
   */
  @Override
  public ${className} modify(${className} entity) {
    ${className} check = find(entity.getId());
    if (check == null) {
      throw new ImsException(String.format("${tableComment}不存在id=%s", entity.getId()));
    }
    BeanUtils.copyPropertiesSkipNull(entity, check);
    int result = update(check).execute();
    if (result < 1) {
      throw new ImsException(String.format("更新${tableComment}失败 entity=%s", entity));
    }
    return check;
  }


  @Override
  public PageInfo<${className}> findPage(int pageNum, int pageSize) {
    //计算总数
    int totalSize = dsl().fetchCount(select());

    PageInfo<${className}> pageInfo = new PageInfo<>(pageNum, pageSize, totalSize);
    int offset = (pageInfo.getPageNum() - 1) * pageInfo.getPageSize();
    List<${className}> list = select().limit(offset, pageInfo.getPageSize()).fetchInto(${className}.class);
    pageInfo.setList(list);
    return pageInfo;
  }


  @Override
  public PageInfo<${className}> findPage(Page page) {
    SelectConditionStep<${className}Record> select = select();
    if (page.getCondition() != null) {
      select.and(page.getCondition());
    }
    //计算总数
    int totalSize = dsl().fetchCount(select);
    if (!CollectionUtils.isEmpty(page.getOrderFields())) {
      select.orderBy(page.getOrderFields());
    }
    PageInfo<${className}> pageInfo = new PageInfo<>(page.getPageNum(), page.getPageSize(), totalSize);
    int offset = (pageInfo.getPageNum() - 1) * pageInfo.getPageSize();

    List<${className}> list = select.limit(offset, pageInfo.getPageSize()).fetchInto(${className}.class);
    pageInfo.setList(list);
    return pageInfo;
  }


  @Override
  public PageInfo<${className}> findPage(${packageBase}.core.model.Page page) {
    SelectConditionStep<${className}Record> select = select();
    if (page.getCondition() != null) {
      select.and(page.getCondition());
    }
    //计算总数
    int totalSize = dsl().fetchCount(select);
    if (!CollectionUtils.isEmpty(page.getOrderFields())) {
      select.orderBy(page.getOrderFields());
    }
    PageInfo<${className}> pageInfo = new PageInfo<>(page.getPageNum(), page.getPageSize(), totalSize);
    int offset = (pageInfo.getPageNum() - 1) * pageInfo.getPageSize();

    List<${className}> list = select.limit(offset, pageInfo.getPageSize()).fetchInto(${className}.class);
    pageInfo.setList(list);
    return pageInfo;
  }

}
